package com.zr.service.driverclient.impl;


import com.zr.dao.car.CarInfoDao;
import com.zr.dao.dispatch.DispatchAbnormalRecordDao;
import com.zr.dao.dispatch.DispatchRouteDao;
import com.zr.dao.dispatch.DispatchTicketDao;
import com.zr.dao.order.OrderFormDao;
import com.zr.dao.order.OrderStatusDao;
import com.zr.service.driverclient.MissionService;
import com.zr.utils.RedisUtil;
import com.zr.utils.SequenceUtil;
import com.zr.vo.car.CarInfo;
import com.zr.vo.dispatch.DispatchAbnormalRecord;
import com.zr.vo.dispatch.DispatchRoute;
import com.zr.vo.dispatch.DispatchTicket;
import com.zr.vo.order.OrderForm;
import com.zr.vo.order.OrderStatus;
import com.zr.websocket.AbnormalSocket;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;


@Service
public class MissionServiceImpl implements MissionService {
    //调度单Dao
    @Resource
    private DispatchTicketDao dispatchTicketDao;
    //订单dao
    @Resource
    private OrderFormDao orderFormDao;

    //订单/调度单状态dao
    @Resource
    private OrderStatusDao orderStatusDao;
    //汽车dao
    @Resource
    private CarInfoDao carInfoDao;
    //异常dao
    @Resource
    private DispatchAbnormalRecordDao dispatchAbnormalRecordDao;

    //线路dao
    @Resource
    private DispatchRouteDao dispatchRouteDao;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private SequenceUtil sequenceUtil;

    /**
     * 根据车牌号获取当前任务
     *
     * @param carNumber
     * @return
     */
    @Override
    public List<DispatchTicket> getDisList(String carNumber) {
        return dispatchTicketDao.selectByCarNumber(carNumber);
    }

    /**
     * 根据车牌号获取历史任务
     *
     * @param carNumber
     * @return
     */
    @Override
    public List<DispatchTicket> getHisDisList(String carNumber) {
        return dispatchTicketDao.selectHisByCarNumber(carNumber);
    }


    /**
     * 修改调度单状态
     *
     * @param dispatchTicket
     * @return
     */
    @Override
    @Transactional
    public int editDispatchTicket(DispatchTicket dispatchTicket) {
        dispatchTicket.setModifyTime(new Date());
        String status = dispatchTicket.getStatus();
        switch (status) {
            case "已拒绝":
                refuse(dispatchTicket);
                break;
            case "待提货":
                onPickUp(dispatchTicket);
                break;
            case "运输中":
                onMove(dispatchTicket);
                dispatchTicket.setActualStartTime(new Date());
                break;
            default:
                break;
        }
        return dispatchTicketDao.updateByPrimaryKeySelective(dispatchTicket);
    }

    /**
     * 待提货操作(接单)
     *
     * @param dispatchTicket
     */
    private void onPickUp(DispatchTicket dispatchTicket) {
        //在状态表中新增数据
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setStatusAddress(dispatchTicket.getStartAreaId());
        orderStatus.setStatusTicketId(dispatchTicket.getTicketId());
        orderStatus.setStatusName(dispatchTicket.getStatus());
        orderStatus.setStatusTime(new Date());
        orderStatusDao.insertSelective(orderStatus);
    }

    /**
     * 运输中操作
     *
     * @param dispatchTicket
     */
    private void onMove(DispatchTicket dispatchTicket) {
        //修改车辆状态
        CarInfo carInfo = new CarInfo();
        carInfo.setNumber(dispatchTicket.getCarNumber());
        carInfo.setCarStatus("运输中");
        carInfoDao.updateLocationByCarNumber(carInfo);
        //在状态表中新增数据
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setStatusAddress(dispatchTicket.getStartAreaId());
        orderStatus.setStatusTicketId(dispatchTicket.getTicketId());
        orderStatus.setStatusName("发车");
        orderStatus.setStatusTime(new Date());
        orderStatusDao.insertSelective(orderStatus);
        //根据调度单id查找订单id
        List<OrderForm> orderFormList = orderFormDao.selectAllByDisPId(dispatchTicket.getId());
        //修改订单状态
        for (OrderForm orderForm : orderFormList) {
            OrderForm orderForm1 = new OrderForm();
            orderForm1.setId(orderForm.getId());
            orderForm1.setCurrentStatus("运输中");
            orderForm1.setUpdateTime(new Date());
            orderFormDao.updateByPrimaryKeySelective(orderForm1);
        }
    }

    /**
     * 拒绝订单时的操作
     *
     * @param dispatchTicket
     */
    private void refuse(DispatchTicket dispatchTicket) {
        //修改车辆状态
        CarInfo carInfo = new CarInfo();
        carInfo.setNumber(dispatchTicket.getCarNumber());
        carInfo.setCarStatus("空闲");
        carInfoDao.updateLocationByCarNumber(carInfo);
        //根据调度单id查找订单id
        List<OrderForm> orderFormList = orderFormDao.selectAllByDisPId(dispatchTicket.getId());
        //修改订单状态
        for (OrderForm orderForm : orderFormList) {
            OrderForm orderForm1 = new OrderForm();
            orderForm1.setId(orderForm.getId());
            orderForm1.setCurrentStatus("待调度");
            orderForm1.setUpdateTime(new Date());
            orderFormDao.updateByPrimaryKeySelective(orderForm1);
        }
    }

    /**
     * 确认收货物
     *
     * @param orderForm
     * @return int
     */
    @Override
    @Transactional
    public int editOrderStatus(OrderForm orderForm) {
        String status = orderForm.getCurrentStatus();
        switch (status) {
            case "待发车":
                onSend(orderForm);
                break;
            case "已送达":
                completeOrder(orderForm);
                break;
            default:
                break;
        }
        return orderFormDao.updateByPrimaryKeySelective(orderForm);
    }

    /**
     * 订单完成时同时更新的数据库
     *
     * @param orderForm
     */
    private void completeOrder(OrderForm orderForm) {
        //在状态表中新增数据
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setStatusTicketId(orderForm.getOrderTicketId());
        orderStatus.setStatusOrderId(orderForm.getOrderId());
        orderStatus.setStatusAddress(orderForm.getConsigneeAddress());
        orderStatus.setStatusName("已送达");
        orderStatus.setStatusTime(new Date());
        orderStatusDao.insertSelective(orderStatus);
        //更新汽车所在地
        CarInfo carInfo = new CarInfo();
        carInfo.setNumber(orderForm.getBaseCarNumber());
        carInfo.setModifyTime(new Date());
        carInfo.setLocation(orderForm.getCurrentLocation());
        carInfoDao.updateLocationByCarNumber(carInfo);
        //更新路线表
        DispatchRoute dispatchRoute = new DispatchRoute();
        dispatchRoute.setTicketId(orderForm.getOrderTicketId());
        dispatchRoute.setAreaId(orderForm.getConsigneeAddress());
        dispatchRoute.setActualAriveTime(orderForm.getCurrentStatusTime());
        dispatchRouteDao.updateArTimeByTidandAid(dispatchRoute);
    }


    /**
     * 提货更新
     *
     * @param orderForm
     */
    private void onSend(OrderForm orderForm) {
        //在状态表中新增数据
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setStatusTicketId(orderForm.getOrderTicketId());
        orderStatus.setStatusOrderId(orderForm.getOrderId());
        orderStatus.setStatusAddress(orderForm.getConsignorAddress());
        orderStatus.setStatusName("提货");
        orderStatus.setStatusTime(new Date());
        orderStatusDao.insertSelective(orderStatus);
    }

    /**
     * 提货后重新获取信息
     *
     * @param dispatchTicket
     * @return
     */
    @Override
    public DispatchTicket getDisInfo(DispatchTicket dispatchTicket) {
        return dispatchTicketDao.selectByPrimaryKey2(dispatchTicket.getId());
    }

    /**
     * 订单全部确认后自动修改调度单状态的方法
     *
     * @param orderForm
     * @return
     */
    @Override
    @Transactional
    public int editDispatchTicketFinal(OrderForm orderForm) {
        List<OrderForm> list = orderFormDao.selectAllBydistid(orderForm.getOrderTicketId());
        boolean isy = true;
        for (OrderForm orderForm1 : list) {
            if (orderForm1.getCurrentStatus().equals("运输中")) {
                isy = false;
                break;
            }
        }
        //判断调度单内订单全部完成，更新调度单及汽车状态
        if (isy) {
            //更新汽车状态
            CarInfo carInfo = new CarInfo();
            carInfo.setNumber(orderForm.getBaseCarNumber());
            carInfo.setCarStatus("空闲");
            carInfoDao.updateLocationByCarNumber(carInfo);
            //在状态表中新增调度单完成数据
            OrderStatus orderStatus = new OrderStatus();
            orderStatus.setStatusTicketId(orderForm.getOrderTicketId());
            orderStatus.setStatusAddress(orderForm.getConsigneeAddress());
            orderStatus.setStatusName("调度单完成");
            orderStatus.setStatusTime(new Date());
            orderStatusDao.insertSelective(orderStatus);
            //更新调度单状态
            DispatchTicket dispatchTicket = new DispatchTicket();
            dispatchTicket.setStatus("已完成");
            dispatchTicket.setModifyTime(new Date());
            dispatchTicket.setActualEndTime(new Date());
            dispatchTicket.setTicketId(orderForm.getOrderTicketId());
            return dispatchTicketDao.updateByTicketId(dispatchTicket);
        }
        return 0;
    }


    /**
     * 上报异常同时更新调度单状态
     *
     * @param dispatchAbnormalRecord
     * @return
     */
    @Override
    @Transactional
    public int abnormal(DispatchAbnormalRecord dispatchAbnormalRecord) {
        //更新调度单状态
        DispatchTicket dispatchTicket = new DispatchTicket();
        dispatchTicket.setTicketId(dispatchAbnormalRecord.getTicketId());
        dispatchTicket.setModifyTime(new Date());
        dispatchTicket.setStatus("异常");
        dispatchTicketDao.updateByTicketId(dispatchTicket);
        String aid = getAidOnRedis();
        //aid存入redis并设置key过期时间（添加异常图片时使用aid作为文件名）
        redisUtil.set("aid", aid, 1L, TimeUnit.MINUTES);
        //websocket给所有管理员发送消息
        AbnormalSocket.send(null, "新异常上报");
        //异常表插入数据
        dispatchAbnormalRecord.setAid(aid);
        dispatchAbnormalRecord.setAbnormalTime(new Date());
        return dispatchAbnormalRecordDao.insertSelective(dispatchAbnormalRecord);
    }

    /**
     * 利用redis获取异常订单编号
     *
     * @return
     */
    private String getAidOnRedis() {
        StringBuffer sb = new StringBuffer();
        String currentDate = new SimpleDateFormat("yyyyMMdd").format(new Date());
        String key = "YC" + currentDate;
        long incr = sequenceUtil.incr(key, 1);
        String code = SequenceUtil.getSequence(incr, 4);
        return sb.append(key).append(code).toString();
    }


}
